package edu.guet.cn.blogbasics.filter;

import com.alibaba.fastjson.JSON;
import edu.guet.cn.blogbasics.common.ResultEnum;
import edu.guet.cn.blogbasics.common.ResultVO;
import edu.guet.cn.blogbasics.entity.JwtAuthUser;
import edu.guet.cn.blogbasics.model.LoginUser;
import edu.guet.cn.blogbasics.utils.JwtTokenUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @Auther: hejianding
 * @Date: 2021/4/8 11:04
 * @Version: 1.0
 */

/**
 * JWTLogin过滤器及其验证，首页的重定向
 */
public class JwtLoginAuthFilter extends UsernamePasswordAuthenticationFilter {

    private AuthenticationManager authenticationManager;
    private ThreadLocal<Boolean> rememberMe=new ThreadLocal<>();

    public JwtLoginAuthFilter(AuthenticationManager authenticationManager){
        this.authenticationManager=authenticationManager;
        //设置过滤器地址
        super.setFilterProcessesUrl("/auth/login");
    }

    /**
     * 登录验证
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) {
        LoginUser loginUser = new LoginUser();
        loginUser.setUsername(request.getParameter("username"));
        loginUser.setPassword(request.getParameter("password"));
        loginUser.setRememberMe(Boolean.parseBoolean(request.getParameter("remember")));
        System.out.println(loginUser.toString());
        rememberMe.set(loginUser.getRememberMe());
        return authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(loginUser.getUsername(),loginUser.getPassword(),new ArrayList<>())
        );
    }

    /**
     * 与AuthenticationSuccessHandler作用相同
     * 登录成功后重定向到home
     * @param request
     * @param response
     * @param chain
     * @param authResult
     * @throws IOException
     * @throws ServletException
     */
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult)throws IOException, ServletException{
        JwtAuthUser jwtAuthUser = (JwtAuthUser) authResult.getPrincipal();
        System.out.println("jwtAuthUser:" + jwtAuthUser.toString());
        boolean isRemember = rememberMe.get();
        List<String> roles = new ArrayList<>();
        Collection<? extends GrantedAuthority> authorities = jwtAuthUser.getAuthorities();
        for (GrantedAuthority authority:authorities){
            roles.add(authority.getAuthority());
        }
        System.out.println("roles:"+roles);
        String token = JwtTokenUtils.createToken(jwtAuthUser.getUsername(), roles, isRemember);

        //响应或者请求的格式
        request.getHeader("Access-Control-Allow-Origin");
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/text");
        response.setCharacterEncoding("utf-8");
//        response.addHeader("Access-Control-Allow-Origin","*");
        //相应前端数据data里的，应该为一个对象最好
        response.getWriter().write(JSON.toJSONString(ResultVO.result(ResultEnum.SUCCESS,token,true,request.getParameter("username"))));
        //重定向无法设置header，这里设置的只能设置到/auth/login的header
        //登录成功重定向到home，这里先采用值传递
//        response.sendRedirect("http://localhost:8080/#/Dashboard.vue?token="+token);
    }

    protected void unsuccessfulAuththentication(HttpServletRequest request,
                                                HttpServletResponse response,
                                                AuthenticationException failed)throws IOException,ServletException{
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(JSON.toJSONString(ResultVO.result(ResultEnum.USER_LOGIN_FAILED,false)));
    }
}
